package com.example.pwj.ffstudy.http;

import android.support.annotation.IntDef;
import android.util.Log;
import android.util.SparseArray;

import com.blankj.utilcode.util.NetworkUtils;
import com.example.pwj.ffstudy.comm.MyApp;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by admin on 2017/3/20.
 */

public class Api {
    private static final String TAG = Api.class.getSimpleName();
    /**
     * 请求超时时间
     */
    private static final int DEFAULT_TIMEOUT = 15;
    private static final int CACHE_SIZE = 10 * 1024 * 1024;// 10 MiB
    private static final String CACHE_PATH = "responses";

    private static final int TYPE_COUNT = 3;
    public static final int TYPE_GANK = 1;
    public static final int TYPE_ZHIHU = 2;
    public static final int TYPE_DOUBAN = 3;

    @IntDef({TYPE_GANK, TYPE_ZHIHU, TYPE_DOUBAN})
    @Retention(RetentionPolicy.SOURCE)
    public @interface UrlType {
    }

    private static SparseArray<ApiService> sApiServices = new SparseArray<>(TYPE_COUNT);

    private Api() {
    }

    public static ApiService getDefault(@UrlType int urlType) {
        ApiService apiService = sApiServices.get(urlType);
        if (apiService == null) {
            apiService = initApi(urlType);
            sApiServices.put(urlType, apiService);
        }
        return apiService;
    }

    private static ApiService initApi(int urlType) {
        File httpCacheDirectory = new File(MyApp.sContext.getCacheDir(), CACHE_PATH);
        Cache cache = new Cache(httpCacheDirectory, CACHE_SIZE);
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.cache(cache)
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .addInterceptor(getHttpLoggingInterceptor())
                .addInterceptor(getCacheInterceptor())
                .addNetworkInterceptor(getCacheInterceptor());
        ApiService apiService = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(Url.getUrlbyType(urlType))
                .build()
                .create(ApiService.class);
        return apiService;
    }

    //日志拦截器
    private static HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                new HttpLoggingInterceptor.Logger() {

                    @Override
                    public void log(String message) {
                        Log.d(TAG, "log = " + message);
                    }

                });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return loggingInterceptor;
    }

    //缓存拦截器
    private static Interceptor getCacheInterceptor() {
        Interceptor commonParams = new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!NetworkUtils.isConnected()) {
                    //无网络下强制使用缓存，无论缓存是否过期,此时该请求实际上不会被发送出去。
                    request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }

                okhttp3.Response response = chain.proceed(request);
                if (NetworkUtils.isConnected()) {
                    //这样在下次请求时，根据缓存决定是否真正发出请求。
                    //当然如果你想在有网络的情况下都直接走网络，那么只需要
                    //将其超时时间这是为0即可:String cacheControl="Cache-Control:public,max-age=0"
                    int maxAge = 60 * 60; // read from cache for 1h
                    return response.newBuilder()
//                            .header("Cache-Control", cacheControl)
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .removeHeader("Pragma")
                            .build();
                } else {
                    //无网络
                    int maxStale = 60 * 60 * 24 * 7;
                    return response.newBuilder()
//                            .header("Cache-Control", "public,only-if-cached,max-stale=360000")
                            .header("Cache-Control", "public,only-if-cached,max-stale=" + maxStale)
                            .removeHeader("Pragma")
                            .build();
                }
            }
        };
        return commonParams;
    }
}
